using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.UI;

namespace WorkFlow.Tools.UI
{
    [ExecuteAlways]
    [RequireComponent(typeof(RawImage))] [RequireComponent(typeof(UIBehaviourDriver))]
    [AddComponentMenu("WorkFlow/UGUI/UIBehaviour/RawImageRatio")]
    public class RawImageRatio : MonoBehaviour, IUIBehaviourDriverElement
    {
        [SerializeField] int order;
        [SerializeField] private bool originalRatio = true;
        [SerializeField] BasedOn basedOn;
        [SerializeField] float basePos;
        [SerializeField][ShowIf("@!originalRatio")] float ratio = 1;
        [SerializeField] private FillType onFill;

        private RawImage _rawImage;
        RawImage URawImage
        {
            get
            {
                if (_rawImage == null)
                    _rawImage = GetComponent<RawImage>();
                return _rawImage;
            }
        }
        private  RectTransform _rectTransform;
        RectTransform URectTransform
        {
            get
            {
                if (_rectTransform == null)
                    _rectTransform = GetComponent<RectTransform>();
                return _rectTransform;
            }
        }
        
        private RectTransform _parentRectTransform;
        RectTransform UParentRectTransform
        {
            get
            {
                if (_parentRectTransform == null)
                    _parentRectTransform = URectTransform.parent.GetComponent<RectTransform>();
                return _parentRectTransform;
            }
        }
        
        bool IUIBehaviourDriverElement.ElementEnabled => enabled;
        int IUIBehaviourDriverElement.Order => order;
        void IUIBehaviourDriverElement.OnRectTransformDimensionsChange()
        {
            ApplyRatio();
        }
        void Start()
        {

        }
        [Button]
        public void ApplyRatio()
        {
            if (!enabled) return;
#if UNITY_EDITOR
            _isValidate = false;
#endif
            if (!enabled) return;
            float tempRatio = ratio;
            if (originalRatio && URawImage.texture != null)
            {
                tempRatio = (float)URawImage.texture.width / URawImage.texture.height;
            }
            
            
            
            URectTransform.sizeDelta = basedOn == BasedOn.BasedOnWidth
                ? new Vector2(URectTransform.sizeDelta.x, URectTransform.rect.width / tempRatio)
                : new Vector2(URectTransform.rect.height * tempRatio, URectTransform.sizeDelta.y);
            if (URectTransform.rect.width == 0 || UParentRectTransform.rect.width == 0 
                                               || URectTransform.rect.height == 0 || UParentRectTransform.rect.height == 0)
                return;
            if (UParentRectTransform != null)
            {
                URectTransform.localScale = UParentRectTransform.rect.width / URectTransform.rect.width * Vector3.one;
                if (onFill == FillType.FillParent)
                {
                    float factHeight = URectTransform.rect.height * URectTransform.localScale.y;
                    if (factHeight > UParentRectTransform.rect.height)
                    {
                        URectTransform.localScale = UParentRectTransform.rect.height / URectTransform.rect.height * Vector3.one;
                    }
                }
                else if (onFill == FillType.FullParent)
                {
                    float factHeight = URectTransform.rect.height * URectTransform.localScale.y;
                    if (factHeight < UParentRectTransform.rect.height)
                    {
                        URectTransform.localScale = UParentRectTransform.rect.height / URectTransform.rect.height * Vector3.one;
                    }
                }
                else
                {
                    URectTransform.localScale = Vector3.one;
                }
            }
        }
    
#if UNITY_EDITOR
        private bool _isValidate;
        bool IUIBehaviourDriverElement.IsValidated => _isValidate;
        void OnValidate()
        {
            _isValidate = true;
        }
#endif
    }
}
